import * as vscode from 'vscode'

// 定义类型以提高类型安全性
type KeywordCategory = 'controls' | 'layouts' | 'sections' | 'groupings' | 'fields' | 'metadata'
type KeywordGroups = Partial<Record<KeywordCategory, string[]>>

// 补全项缓存
let cachedCompletionItems: vscode.CompletionItem[] | null = null

// 添加关键字描述信息的接口
interface KeywordInfo {
	word: string
	description: string
	example?: string
	syntax?: string
	notes?: string[]
}

// 扩展关键字组，添加描述信息
const keywordInfoGroups: Record<KeywordCategory, KeywordInfo[]> = {
	controls: [
		{
			word: 'DateEdit',
			description: '日期编辑控件，用于输入和显示日期',
			syntax: 'DateEdit field_name { attributes }',
			example: 'DateEdit birth_date {\n    format: "yyyy-MM-dd"\n    required: true\n}',
			notes: [
				'支持多种日期格式',
				'可以设置日期范围限制',
				'支持键盘快捷操作'
			]
		},
		{
			word: 'ComboBox',
			description: '下拉框控件，用于从预定义选项中选择',
			syntax: 'ComboBox field_name { items: [...] }',
			example: 'ComboBox status {\n    items: ["Active", "Inactive", "Pending"]\n}',
			notes: [
				'支持动态加载选项',
				'可以设置为可编辑模式',
				'支持多选模式'
			]
		},
		{ word: 'TextEdit', description: '文本编辑控件，用于输入和编辑文本' },
		{ word: 'ButtonEdit', description: '按钮编辑控件，结合编辑框和按钮功能' },
		{ word: 'Edit', description: '基础编辑控件' },
		{ word: 'Label', description: '标签控件，用于显示静态文本' }
	],
	layouts: [
		{
			word: 'VBox',
			description: '垂直布局容器',
			syntax: 'VBox name { children: [...] }',
			example: 'VBox mainLayout {\n    children: [button1, button2]\n}',
			notes: [
				'支持垂直布局',
				'可以添加多个子元素',
				'支持自动布局'
			]
		},
		{
			word: 'HBox',
			description: '水平布局容器',
			syntax: 'HBox name { children: [...] }',
			example: 'HBox mainLayout {\n    children: [button1, button2]\n}',
			notes: [
				'支持水平布局',
				'可以添加多个子元素',
				'支持自动布局'
			]
		},
		{
			word: 'Grid',
			description: '网格布局容器，用于创建灵活的网格布局',
			syntax: 'Grid name { columns: n }',
			example: 'Grid mainLayout {\n    columns: 2\n    spacing: 10\n}',
			notes: [
				'支持自动布局和固定布局',
				'可以设置行列间距',
				'支持单元格合并'
			]
		},
		{ word: 'Folder', description: '文件夹容器' },
		{ word: 'Page', description: '页面容器' }
	],
	sections: [
		{ word: 'SCHEMA', description: '模式定义' },
		{ word: 'INSTRUCTIONS', description: '指令' },
		{ word: 'SCREEN', description: '屏幕' },
		{ word: 'RECORD', description: '记录' },
		{ word: 'TABLES', description: '表格' },
		{ word: 'ATTRIBUTES', description: '属性' },
		{ word: 'LAYOUT', description: '布局' },
		{ word: 'END', description: '结束' }
	],
	groupings: [
		{ word: 'Group', description: '组' },
		{ word: 'Master Item', description: '主项目' },
		{ word: 'Labor Completion', description: '劳动完成' },
		{ word: 'Overhead Completion', description: '间接费用完成' }
	],
	fields: [
		{ word: 'InQty', description: '输入数量' },
		{ word: 'Qty', description: '数量' },
		{ word: 'Unit', description: '单位' },
		{ word: 'W/O No', description: '工作单号' },
		{ word: 'Year/Month', description: '年/月' },
		{ word: 'Cost Calculation Method', description: '成本计算方法' },
		{ word: 'Category No', description: '类别号' },
		{ word: 'G', description: '通用' },
		{ word: 'Work hour', description: '工作小时' },
		{ word: 'Material', description: '材料' },
		{ word: 'Labor', description: '劳动' },
		{ word: 'Overhead', description: '间接费用' },
		{ word: 'Process', description: '过程' },
		{ word: 'Total', description: '总计' }
	],
	metadata: [
		{ word: 'Record Owner', description: '记录所有者' },
		{ word: 'Create/Modify Date', description: '创建/修改日期' },
		{ word: 'Record Orig', description: '记录来源' },
		{ word: 'Dept Orig', description: '部门来源' }
	]
}

// 更新 keywordGroups 以保持向后兼容
const keywordGroups: KeywordGroups = Object.fromEntries(
	Object.entries(keywordInfoGroups).map(([category, infos]) => [
		category,
		infos.map(info => info.word)
	])
)

// 预编译模式以提高性能
const symbolDefinitions = [
	{
		pattern: /^(Grid|LAYOUT|Page|VBox|Folder|TABLES|INSTRUCTIONS)/,
		kind: vscode.SymbolKind.Struct,
		completionKind: vscode.CompletionItemKind.Struct
	},
	{
		pattern: /^SCHEMA/,
		kind: vscode.SymbolKind.Key,
		completionKind: vscode.CompletionItemKind.Keyword
	}
].map(def => ({
	...def,
	pattern: new RegExp(def.pattern.source, 'i') // 不区分大小写以提高匹配效果
}))

// 优化的补全提供程序
class PerCompletionItemProvider implements vscode.CompletionItemProvider {
	provideCompletionItems(): vscode.ProviderResult<vscode.CompletionItem[]> {
		// 如果有缓存则使用缓存
		if (cachedCompletionItems) {
			return cachedCompletionItems
		}

		// 创建并缓存补全项
		cachedCompletionItems = Object.entries(keywordGroups).flatMap(([category, words]) =>
			words.map(word => {
				const item = new vscode.CompletionItem(word)
				item.kind = this.getCompletionKindForCategory(category as KeywordCategory)
				return item
			})
		)

		return cachedCompletionItems
	}

	private getCompletionKindForCategory(category: KeywordCategory): vscode.CompletionItemKind {
		switch (category) {
			case 'controls': return vscode.CompletionItemKind.Class
			case 'layouts': return vscode.CompletionItemKind.Struct
			case 'sections': return vscode.CompletionItemKind.Keyword
			case 'groupings': return vscode.CompletionItemKind.Interface
			case 'fields': return vscode.CompletionItemKind.Field
			case 'metadata': return vscode.CompletionItemKind.Property
			default: return vscode.CompletionItemKind.Text
		}
	}
}

// 优化的文档符号提供程序
class PerDocumentSymbolProvider implements vscode.DocumentSymbolProvider {
	private symbolCache = new WeakMap<vscode.TextDocument, vscode.DocumentSymbol[]>()

	provideDocumentSymbols(document: vscode.TextDocument, token: vscode.CancellationToken): vscode.ProviderResult<vscode.DocumentSymbol[]> {
		// 首先检查缓存
		const cached = this.symbolCache.get(document)
		if (cached) {
			return cached
		}

		const symbols: vscode.DocumentSymbol[] = []
		const lines = document.getText().split('\n')

		// 分块处理行以提高性能
		const chunkSize = 1000
		for (let i = 0; i < lines.length; i += chunkSize) {
			if (token.isCancellationRequested) {
				break
			}

			const chunk = lines.slice(i, i + chunkSize)
			this.processChunk(chunk, i, document, symbols)
		}

		// 缓存结果
		this.symbolCache.set(document, symbols)
		return symbols
	}

	private processChunk(lines: string[], startIndex: number, document: vscode.TextDocument, symbols: vscode.DocumentSymbol[]) {
			lines.forEach((line, index) => {
				const lineNumber = startIndex + index
				const range = new vscode.Range(
					new vscode.Position(lineNumber, 0),
					new vscode.Position(lineNumber, line.length)
				)

				for (const def of symbolDefinitions) {
					if (def.pattern.test(line)) {
						symbols.push(new vscode.DocumentSymbol(
							line.trim(),
							'',
							def.kind,
							range,
							range
						))
						break
					}
				}
			})
	}
}

// 添加悬浮提示提供程序
class PerHoverProvider implements vscode.HoverProvider {
	provideHover(
		document: vscode.TextDocument,
		position: vscode.Position,
		token: vscode.CancellationToken
	): vscode.ProviderResult<vscode.Hover> {
		const range = document.getWordRangeAtPosition(position)
		if (!range) return null

		const word = document.getText(range)
		const keywordInfo = this.findKeywordInfo(word)

		if (keywordInfo) {
			const mdString = new vscode.MarkdownString()
			mdString.isTrusted = true
			mdString.supportHtml = true

			// 添加标题和类型
			const category = this.findKeywordCategory(word)
			const categoryName = category ? this.getCategoryDisplayName(category) : ''
			mdString.appendMarkdown(`## ${keywordInfo.word}\n`)
			mdString.appendMarkdown(`<span style="color:#888">类型：${categoryName}</span>\n\n`)

			// 添加描述
			mdString.appendMarkdown(`${keywordInfo.description}\n\n`)

			// 添加语法
			if (keywordInfo.syntax) {
				mdString.appendMarkdown('### 语法\n```per\n')
				mdString.appendMarkdown(keywordInfo.syntax)
				mdString.appendMarkdown('\n```\n\n')
			}

			// 添加示例
			if (keywordInfo.example) {
				mdString.appendMarkdown('### 示例\n```per\n')
				mdString.appendMarkdown(keywordInfo.example)
				mdString.appendMarkdown('\n```\n\n')
			}

			// 添加注意事项
			if (keywordInfo.notes?.length) {
				mdString.appendMarkdown('### 注意事项\n')
				keywordInfo.notes.forEach(note => {
					mdString.appendMarkdown(`- ${note}\n`)
				})
			}

			return new vscode.Hover(mdString)
		}

		return null
	}

	private findKeywordInfo(word: string): KeywordInfo | undefined {
		for (const infos of Object.values(keywordInfoGroups)) {
			const info = infos.find(i => i.word.toLowerCase() === word.toLowerCase())
			if (info) return info
		}
		return undefined
	}

	private findKeywordCategory(word: string): KeywordCategory | undefined {
		for (const [category, infos] of Object.entries(keywordInfoGroups)) {
			if (infos.some(info => info.word.toLowerCase() === word.toLowerCase())) {
				return category as KeywordCategory
			}
		}
		return undefined
	}

	private getCategoryDisplayName(category: KeywordCategory): string {
		switch (category) {
			case 'controls': return '控件'
			case 'layouts': return '布局'
			case 'sections': return '段落'
			case 'groupings': return '组'
			case 'fields': return '字段'
			case 'metadata': return '元数据'
			default: return '未知'
		}
	}
}

export function activate(context: vscode.ExtensionContext) {
	// 注册提供程序
	const completionProvider = new PerCompletionItemProvider()
	const symbolProvider = new PerDocumentSymbolProvider()
	const hoverProvider = new PerHoverProvider()

	// 添加可释放资源
	context.subscriptions.push(
		vscode.languages.registerCompletionItemProvider('per', completionProvider),
		vscode.languages.registerDocumentSymbolProvider('per', symbolProvider),
		vscode.languages.registerHoverProvider('per', hoverProvider),
		// 配置更改时清除缓存
		vscode.workspace.onDidChangeConfiguration(() => {
			cachedCompletionItems = null
		})
	)
}

export function deactivate() {
	cachedCompletionItems = null
}
